package com.zhongwang.mms.module.allocation.service;

import com.zhongwang.mms.common.JsonResult;
import com.zhongwang.mms.gen.entity.AllocationOrder;
import com.zhongwang.mms.gen.entity.MOrder;
import com.zhongwang.mms.gen.entity.PInventory;
import com.zhongwang.mms.gen.entity.POrder;
import com.zhongwang.mms.module.allocation.dao.AllocationOrderDao;
import com.zhongwang.mms.module.allocation.dao.AllocationOrderDetailDao;
import com.zhongwang.mms.module.allocation.model.AllocationOrderModel;
import com.zhongwang.mms.module.half.service.HBasicService;
import com.zhongwang.mms.module.material.model.MOrderDetailModel;
import com.zhongwang.mms.module.material.model.MOrderInsertModel;
import com.zhongwang.mms.module.material.service.MOrderService;
import com.zhongwang.mms.module.purchase.constant.PurchaseConstant;
import com.zhongwang.mms.module.purchase.dao.PurChangeDao;
import com.zhongwang.mms.module.purchase.dao.PurPInventoryDao;
import com.zhongwang.mms.module.purchase.dao.PurPOrderDao;
import com.zhongwang.mms.module.purchase.dao.PurPOrderDetailDao;
import com.zhongwang.mms.module.purchase.model.*;
import com.zhongwang.mms.module.purchase.service.PurWarOutManageService;
import com.zhongwang.mms.module.system.log.LogService;
import com.zhongwang.mms.util.ShiroUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @description:调拨出库
 * @author: th
 * @time: 2020/8/18 8:07
 */
@Service
@Slf4j
public class AllocationOutWarService {

    @Autowired
    private AllocationOrderDetailDao allocationOrderDetailDao;
    @Autowired
    private AllocationOrderDao allocationOrderDao;
    @Autowired
    private PurPInventoryDao purPInventoryDao;
    @Autowired
    private PurPOrderDao purPOrderDao;
    @Autowired
    private PurWarOutManageService purWarOutManageService;
    @Autowired
    private PurChangeDao purChangeDao;
    @Autowired
    private LogService logService;
    @Autowired
    private PurPOrderDetailDao purPOrderDetailDao;
    @Autowired
    private MOrderService mOrderService;
    @Autowired
    private HBasicService hBasicService;

    public List<AllocationOrderModel> selectOrderDetailByOdrId(Integer ardOdrId) {

        return allocationOrderDetailDao.selectOrderDetailByOdrId(ardOdrId);
    }

    /**
     * 出库操作
     * @param param
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult saveAllocationOutWar(AllocationOrderModel param) {

        //获取调拨主单信息
        AllocationOrderModel allocationOrder = allocationOrderDao.selectAllByPrimaryKey(param.getOdrId());
        //获取调拨明细列表
        List<AllocationOrderModel> list = selectOrderDetailByOdrId(param.getOdrId());
        AllocationOrder allocationOrder1 = new AllocationOrder();
        if(allocationOrder.getOdrType() == 1 || allocationOrder.getOdrType() == 3){
            POutOrder pOutOrder = new POutOrder();
            List<POrderDetail> pOrderDetails = allocationOrderDetailDao.selectPurDetailByOdrId(param.getOdrId());
            pOutOrder.setInsertData(pOrderDetails);
            com.zhongwang.mms.module.purchase.model.POrder pOrder = new com.zhongwang.mms.module.purchase.model.POrder();
            pOrder.setOdrDate(param.getOdrDate());
            pOrder.setOdrRemark(param.getOdrRemark());
            //pOrder.setOdrTakePerson(param.getOdrTakePerson());
            //pOrder.setOdrTakeWorkshopId(param.getOdrDept());
            pOrder.setOdrRepId(allocationOrder.getOdrCode());
            pOutOrder.setFormData(pOrder);

            return purOutWar(pOutOrder,param.getOdrId());
        }else if(allocationOrder.getOdrType() == 2){
            MOrderInsertModel mOrderInsertModel = new MOrderInsertModel();
            List<MOrderDetailModel> mOrderDetailModels = allocationOrderDetailDao.selectMatDetailByOdrId(param.getOdrId());
            mOrderInsertModel.setInsertData(mOrderDetailModels);
            MOrder mOrder = new MOrder();
            mOrder.setOdrDate(param.getOdrDate());
            mOrder.setOdrRemark(param.getOdrRemark());
            //mOrder.setOdrTakePerson(param.getOdrTakePerson());
            mOrder.setOdrType(5);
            mOrder.setOdrRepId(allocationOrder.getOdrCode());
            //mOrder.setOdrTakeWorkshop(hBasicService.getDeptNameById(param.getOdrDept()).getDepName());
            mOrderInsertModel.setFormData(mOrder);
            String msg = mOrderService.saveOutOrderModel(mOrderInsertModel);
            JsonResult jsonResult = new JsonResult();
            if (!msg.contains("保存失败")) {
                jsonResult.setType(JsonResult.ResultType.SUCCESS);
                allocationOrder1.setOdrOutStatus(2);
                allocationOrder1.setOdrId(param.getOdrId());
                allocationOrderDao.updateByPrimaryKeySelective(allocationOrder1);
            }
            jsonResult.setMsg(msg);

            return jsonResult;
        }
        return null;
    }

    /**
     * 外购件出库
     * @param pOutOrder
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult purOutWar(POutOrder pOutOrder,Integer id) {
        //验证
        JsonResult jsonResult = new JsonResult();
        List<String> result = new ArrayList<>();
        for (int i = 0; i < pOutOrder.getInsertData().size(); i++) {
            if (pOutOrder.getInsertData().get(i).getOdaNum() == null || pOutOrder.getInsertData().get(i).getOdaNum() == 0) {
                result.add("\n第" + (i + 1) + "行" + " 数量为空 为空<br>");
            } else if (pOutOrder.getInsertData().get(i).getOdaNum() <= 0) {
                result.add("\n第" + (i + 1) + "行" + " 数量必须大于0 数量<br>");
            } else if (pOutOrder.getInsertData().get(i).getOdaNum() > purPInventoryDao.findByPrimaryKey(pOutOrder.getInsertData().get(i).getItyId()).getItyAvaNum()) {
                result.add("\n第" + (i + 1) + "行" + " 数量大于库存可用数量 数量<br>");
            }
        }
        if (result.size() == 0) {
            List<com.zhongwang.mms.module.purchase.model.POrderDetail> recordList = new ArrayList<>();
            for (int i = 0; i < pOutOrder.getInsertData().size(); i++) {
                boolean exist = false;
                for (int j = 0; j < recordList.size(); j++) {
                    if (recordList.get(j).getItyId().equals(pOutOrder.getInsertData().get(i).getItyId())) {
                        exist = true;
                        recordList.get(j).setOdaNum(recordList.get(j).getOdaNum() + pOutOrder.getInsertData().get(i).getOdaNum());
                        if (recordList.get(j).getOdaNum() > purPInventoryDao.findByPrimaryKey(recordList.get(j).getItyId()).getItyAvaNum()) {
                            List<Integer> errorList = recordList.get(j).getErrorLineNumlist();
                            errorList.add(i + 1);
                            recordList.get(j).setErrorLineNumlist(errorList);
                        }
                    }
                }
                if (exist == false) {
                    com.zhongwang.mms.module.purchase.model.POrderDetail obj = pOutOrder.getInsertData().get(i);
                    obj.getErrorLineNumlist().add(i + 1);
                    recordList.add(obj);
                }
            }
            for (int i = 0; i < recordList.size(); i++) {
                Double avaNum = purPInventoryDao.findByPrimaryKey(recordList.get(i).getItyId()).getItyAvaNum();
                if (recordList.get(i).getErrorLineNumlist().size() > 1) {
                    result.add("\n第" + (recordList.get(i).getErrorLineNumlist().toString()) + "行" + " 是一个库存其出库数之和大于库存可用量，无法出库,当前物料库存可用数量为【" + new BigDecimal(avaNum) + "】 数量<br>");
                }
            }
        }
        if (result.size() > 0) {
            result.add("\n单据保存失败，请先维护以上出库信息！");
            jsonResult.setData(result);
            return jsonResult;
        }
        //创建主单数据
        POrder pOrder = new POrder();
        pOrder.setOdrCode(purWarOutManageService.getOrderCode(PurchaseConstant.PCK));
        pOrder.setOdrRemark(pOutOrder.getFormData().getOdrRemark());
        pOrder.setOdrTakePerson(pOutOrder.getFormData().getOdrTakePerson());
        pOrder.setOdrMakePersonId(ShiroUtils.getUser().getId());
        pOrder.setOdrChangeFlag(0);
        pOrder.setOdrType(2);
        pOrder.setOdrRedFlag(0);
        pOrder.setOdrDate(pOutOrder.getFormData().getOdrDate());
        pOrder.setOdrReqFlag(1);
        pOrder.setOdrMakeDate(new Date());
        pOrder.setOdrTakeWorkshopId(pOutOrder.getFormData().getOdrTakeWorkshopId());
        pOrder.setOdrRepId(pOutOrder.getFormData().getOdrRepId());
        pOrder.setOdrOutType(4);
        purPOrderDao.insert(pOrder);
        Integer odrId = pOrder.getOdrId();
        AllocationResaultModel allocationResaultModel = new AllocationResaultModel();
        allocationResaultModel.setIsChangeFlag(0);
        try {
            //创建明细单
            for (com.zhongwang.mms.module.purchase.model.POrderDetail pOrderDetailModel : pOutOrder.getInsertData()) {
                PInventory pInventory = purPInventoryDao.findByPrimaryKey(pOrderDetailModel.getItyId());
                if (pInventory.getItyChangeFlag() != null && pInventory.getItyChangeFlag() != 2) {
                    allocationResaultModel.setIsChangeFlag(1);
                    //1.溯源：找回此物料最原始的串料信息，即始祖库存信息，找寻方式，
                    //通过此库存ID在串料执后的信息中获取上一级，以此类推。
                    PInventoryModel pInventoryModel = purWarOutManageService.findAncestorChangeData(pInventory.getItyId());
                    //2.累计计算剩余库存量：通过始祖信息获取子孙的在库数量与本身的在库数量之和就是真实在库数量之和
                    //pOrderDetailModel.setOdaNumSource(pInventoryModel.getItyNum() + getChangeOrderInvCount(pInventoryModel.getItyId()));
                    PInventory getNumModel = new PInventory();
                    getNumModel.setItyNum(pInventoryModel.getItyNum());
                    getNumModel.setItyId(pInventoryModel.getItyId());
                    pOrderDetailModel.setOdaNumSource(purWarOutManageService.getChangePInventoryAllNum(getNumModel));
                    pOrderDetailModel.setOdaProCodeSource(pInventoryModel.getItyProCode());
                    pOrderDetailModel.setOdaProNameSource(pInventoryModel.getItyProName());
                    //3.更改串料状态为串料出库状态
                    PChangeOrderModel pChangeOrderModel = purChangeDao.getChangeCountByCeoNeedItyId(pOrderDetailModel.getItyId());
                    if (pChangeOrderModel != null) {
                        //4.2020年7月15日午休后：盖世奇说：.所串料都被出库完毕才能算串料，否则一直是执行
                        PInventory changePInv = purPInventoryDao.getPInventoryByPK(pChangeOrderModel.getCeoNeedItyId());
                        if (changePInv.getItyNum().equals(pOrderDetailModel.getOdaNum()) && pChangeOrderModel.getCeoAppyStatus().equals(3)) {
                            pChangeOrderModel.setCeoAppyStatus(5);
                            purChangeDao.updatePChangeOrderCeoAppyStatusByPk(pChangeOrderModel);
                        }
                    }
                }
                com.zhongwang.mms.gen.entity.POrderDetail pOrderDetail = new com.zhongwang.mms.gen.entity.POrderDetail();
                pOrderDetail.setOdaType(2);
                pOrderDetail.setOdaOdrId(odrId);
                pOrderDetail.setOdaRedFlag(0);
                pOrderDetail.setOdaMatCode(pOrderDetailModel.getOdaMatCode());
                pOrderDetail.setOdaSapCode(pOrderDetailModel.getOdaSapCode());
                pOrderDetail.setOdaMatDesc(pOrderDetailModel.getOdaMatDesc());
                pOrderDetail.setOdaNum(pOrderDetailModel.getOdaNum());
                pOrderDetail.setOdaNumUnit(pOrderDetailModel.getOdaNumUnit());
                pOrderDetail.setOdaTotalPrice(pInventory.getItyPrice() * pOrderDetailModel.getOdaNum());
                pOrderDetail.setOdaNumPrice(pInventory.getItyPrice());
                pOrderDetail.setOdaStockType(pInventory.getItyStockType());
                pOrderDetail.setOdaTrackCode(pOrderDetailModel.getOdaTrackCode());
                pOrderDetail.setOdaProName(pOrderDetailModel.getOdaProName());
                pOrderDetail.setOdaProCode(pOrderDetailModel.getOdaProCode());
                pOrderDetail.setOdaPosition(pOrderDetailModel.getOdaPosition());
                pOrderDetail.setOdaTakeType(pOrderDetailModel.getOdaTakeType());
                pOrderDetail.setOdaWhiId(pOrderDetailModel.getOdaOutWhiId());
                if (pOrderDetailModel.getOdaBookkeepingDate() != null) {
                    pOrderDetail.setOdaBookkeepingDate(new SimpleDateFormat("yyyy-MM-dd").parse(pOrderDetailModel.getOdaBookkeepingDate().replace('.', '-')));
                }
                pOrderDetail.setOdaSpec(pOrderDetailModel.getOdaSpec());
                pOrderDetail.setOdaOutItyId(pOrderDetailModel.getItyId());
                PInventoryModel pInventoryModel = purWarOutManageService.findAncestorChangeData(pInventory.getItyId());
                pOrderDetail.setOdaAtThatTimeAncestorsNum(pOrderDetailModel.getOdaNumSource());
                pOrderDetail.setOdaAtThatTimeAncestorsProCode(pInventoryModel.getItyProCode());
                pOrderDetail.setOdaAtThatTimeAncestorsTrackCode(pInventoryModel.getItyTrackCode());
                pOrderDetail.setOdaOutWhiId(pInventoryModel.getWhiId());
                pOrderDetail.setOdaWhiId(pInventoryModel.getWhiId());
                pOrderDetail.setContractNo(pInventoryModel.getContractNo());
                pOrderDetail.setOdaBrand(pInventoryModel.getItyBrand());
                purPOrderDetailDao.insert(pOrderDetail);
                PInventory changeNum = new PInventory();
                changeNum.setItyId(pOrderDetailModel.getItyId());
                changeNum.setItyNum(pInventory.getItyNum() - pOrderDetailModel.getOdaNum());
                Double avaNum = pInventory.getItyAvaNum() - pOrderDetailModel.getOdaNum();
                if (avaNum < 0) {
                    avaNum = 0d;
                }
                changeNum.setItyAvaNum(avaNum);
                if(changeNum.getItyNum()<0 || changeNum.getItyAvaNum()<0){
                    Exception exception =  new Exception();
                    throw exception;
                }
                if(purPInventoryDao.updatePInventoryNumPrimaryKey(changeNum)==0){
                    Exception exception =  new Exception();
                    throw exception;
                }
            }
            //其中过程中所有库存信息中的数量不可被调整
            allocationResaultModel.setInsertData(pOutOrder.getInsertData());
            allocationResaultModel.setMessage("单据保存成功！");
            allocationResaultModel.setOdrCode(pOrder.getOdrCode());
            jsonResult.setData(allocationResaultModel);
            jsonResult.setType(JsonResult.ResultType.SUCCESS);

            AllocationOrder allocationOrder1 = new AllocationOrder();
            allocationOrder1.setOdrOutStatus(2);
            allocationOrder1.setOdrId(id);
            allocationOrderDao.updateByPrimaryKeySelective(allocationOrder1);
            //记录操作日志
            logService.saveLog("出入库操作-调拨出库", "出库单据编码：" + pOrder.getOdrCode());
        } catch (Exception ex) {
            //记录异常错误日志信息
            log.error("【调拨出库-异常日志】:异常出库单编码：" + pOrder.getOdrCode() + "{" + ex.getMessage() + "}");
            jsonResult.setMsg("单据保存失败,请检查出库库存的数量是否充足！");
        }
        return jsonResult;
    }
}
